package review.generate;

import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import freemarker.template.Configuration;
import freemarker.template.Template;

public class EntityGenerator {

  public static void generator(String config, String template, String daoTemplate) throws Exception {
    Map<String, Object> mapConfig = Config.readConfig(config);
    if (!mapConfig.containsKey("project.package")) {
      throw new RuntimeException("缺少包名");
    }
    if (!mapConfig.containsKey("entity.table")) {
      throw new RuntimeException("缺少表名");
    }
    // 实体包名
    String packageName = mapConfig.get("package.entity").toString().trim();
    String daoPackage = mapConfig.get("package.dao").toString().trim();
    String className = mapConfig.get("entity.class").toString().trim();
    // 项目源代码绝对地址
    String url = Config.getBasePath() + "/src/main/java";
    File path = new File(url, packageName.replaceAll("[.]", "/"));
    if (!path.exists()) {
      path.mkdirs();
    }
    File daoPath = new File(url, daoPackage.replaceAll("[.]", "/"));
    if (!daoPath.exists()) {
      daoPath.mkdirs();
    }
    // 实体类源文件
    String filename = className + ".java";
    File configPath = new File(Config.getBasePath(), "/target/classes/config");
    Configuration configuration = new Configuration(Configuration.VERSION_2_3_0);
    configuration.setDefaultEncoding("UTF-8");
    configuration.setDirectoryForTemplateLoading(configPath);
    Template tmp = configuration.getTemplate(template);
    FileWriter writer = new FileWriter(new File(path, filename));
    Map<String, Object> model = Config.getEntityModel(mapConfig);
    tmp.process(model, writer);
    writer.close();

    // dao源文件
    String daoFile = className + "DAO.java";
    tmp = configuration.getTemplate(daoTemplate);
    writer = new FileWriter(new File(daoPath, daoFile));
    tmp.process(model, writer);
    writer.close();

    File modelPath = new File(path, "model");
    if (!modelPath.exists()) {
      modelPath.mkdirs();
    }
    @SuppressWarnings("unchecked")
    List<PropertyBean> beans = (List<PropertyBean>) model.get("properties");
    tmp = configuration.getTemplate("model_action.ftl");
    // 枚举对象
    for (PropertyBean bean : beans) {
      if (bean.getEnums() != null && bean.getEnums().length > 0) {
        String enumName = className + upcaseFirstChar(bean.getName()) + "Enum";
        FileWriter out = new FileWriter(new File(modelPath, enumName + ".java"));
        PrintWriter print = new PrintWriter(out);
        print.printf("package %s.model;\n", packageName);
        print.println();
        print.printf("public enum %s {\n", enumName);
        StringBuilder eBuilder = new StringBuilder();
        for (int i = 0; i < bean.getEnums().length; i++) {
          eBuilder.append(bean.getEnums()[i].trim().toUpperCase()).append(",");
        }
        int last = eBuilder.lastIndexOf(",");
        eBuilder.deleteCharAt(last).append(";");
        print.printf("  %s\n}", eBuilder.toString());
        print.flush();
        print.close();
        Map<String, Object> configAction = new HashMap<>();
        configAction.put("packageName", packageName + ".model");
        configAction.put("projectPackage", mapConfig.get("project.package"));
        configAction.put("enumName", enumName);
        createEnumAction(configAction, tmp);
      }
    }
  }

  /**
   * 创建枚举对象对应的action，该action可以获取枚举对象所有的值，用于下拉列表框或者表格中显示格式
   * 
   * @param config
   * @param tmp
   * @throws Exception
   */
  public static void createEnumAction(Map<String, Object> config, Template tmp) throws Exception {
    String packageName = config.get("projectPackage").toString() + ".action";
    String url = Config.getBasePath() + "/src/main/java";
    File path = new File(url, packageName.replaceAll("[.]", "/"));
    String filename = "Enum" + config.get("enumName") + "Action.java";
    FileWriter writer = new FileWriter(new File(path, filename));
    tmp.process(config, writer);
    writer.close();
  }

  public static String upcaseFirstChar(String s) {
    if (s != null && s.trim().length() > 0) {
      s = s.trim();
      char frist = s.charAt(0);
      frist = Character.toUpperCase(frist);
      return frist + s.substring(1);
    }
    return s;
  }

  public static void main(String[] args) throws Exception {
    EntityGenerator.generator("config.config_view", "entity.ftl", "dao.ftl");
  }

}